public class AccountEntitlementListController{

    //
    // Tests
    //
    
    static testMethod void testAccountEListNewCase() {
        Test.setCurrentPage(Page.AccountEntitlementListPage);
        UT_SObjectFactory.InterconnectedSObjectsForMASP masp = 
            new UT_SObjectFactory.InterconnectedSObjectsForMASP(1);
        ApexPages.StandardController sc = new ApexPages.StandardController(masp.a);
        AccountEntitlementListController con = new AccountEntitlementListController(sc);

        // Simulate command link click action to test Case create
        ApexPages.currentPage().getParameters().putAll( 
            new Map<String,String>{
                'strFunc' => 'newcasefromentitlement',
                'idSP' => masp.sp.Id,
                'strEntName' => [Select Name From Entitlement__c Where Id=:masp.eArr[0].Id].Name,
                'idEnt' => masp.eArr[0].Id }
        );
        PageReference pr = con.CreateNewCase();
        system.assertEquals(true,pr.getRedirect(),'PageRef for new case should be live');
    }
    
    static testMethod void testAccountEListDropdown() {
        Test.setCurrentPage(Page.AccountEntitlementListPage);
        UT_SObjectFactory.InterconnectedSObjectsForMASP masp = 
            new UT_SObjectFactory.InterconnectedSObjectsForMASP(1);
        ApexPages.currentPage().getParameters().put('id', masp.a.Id);
        ApexPages.StandardController sc = new ApexPages.StandardController(masp.a);
        AccountEntitlementListController con = new AccountEntitlementListController(sc);
        
        String dropdown = con.SelectedSP;
        system.assertEquals('All',con.SelectedSP);
        con.SelectedSP = 'All';
        system.assertEquals('All',con.SelectedSP);
        
        List<EntitlementList.EntitlementWrapper> lstEnt = con.getEntitlement();
        system.assertEquals( 1,con.getNumEntitlements(),'Should have 1 ent.' );       
        con.SelectedSP = masp.sp.Id;
        system.assertEquals( 1,con.getNumEntitlements(),'Should still have 1 ent.' );       
    }
    
    static testMethod void testLoadSupportPrograms_OneSPWithTwoEnts() {
        // One account pointing to one SP which has two child entitlements.  We'll verify that
        // the "All" view shows both of the two entitlements.
        UT_SObjectFactory.InterconnectedSObjectsForMASP masp = 
            new UT_SObjectFactory.InterconnectedSObjectsForMASP(2);
        Support_Program__c sp = masp.sp;
        Entitlement__c e1 = masp.eArr[0];
        Entitlement__c e2 = masp.eArr[1];
        Account a = masp.a;

        // Set up the VF page
        Test.setCurrentPage(Page.AccountEntitlementListPage);
        ApexPages.currentPage().getParameters().put('id',a.Id);
        ApexPages.StandardController sc = new ApexPages.StandardController(a);
        AccountEntitlementListController ctx = new AccountEntitlementListController(sc);
        
        // Verify that select list only has two choices (All and TESTTEST_SP)
        List<SelectOption> lstItems = ctx.getSPOptions();
        //system.debug('>>>'+lstItems[0]);
        //system.debug('>>>'+lstItems[1]+'\n\n\n');
        system.assertEquals(2,lstItems.size());
        system.assertEquals('All', lstItems[0].getLabel());
        system.assertEquals('TEST-MASP', lstItems[1].getLabel());     
        
        // First test:  select list is set to all and we expect two SPs in the list
        ctx.SelectedSP = 'All';
        List<EntitlementList.EntitlementWrapper> lstSPEs = ctx.getEntitlement();
        for(integer i=0; i<lstSPEs.size(); ++i) system.debug('\n\n\n>>>lstSPEs[i]='+lstSPEs[i]+'\n\n\n');
        system.assertEquals(2,lstSPEs.size());
        system.assertEquals('TEST-MASP', lstSPEs[0].getSPName());
        system.assertEquals('TEST-MASP', lstSPEs[1].getSPName());
        system.assertEquals('TEST_E-0', lstSPEs[0].getEntitlement().Name);
        system.assertEquals('TEST_E-1', lstSPEs[1].getEntitlement().Name);        
        
        // Second test:  set select list to the SP, expect same results again 
        ctx.SelectedSP = sp.Id;
        lstSPEs = ctx.getEntitlement();
        system.assertEquals(2,lstSPEs.size());
        system.assertEquals('TEST-MASP', lstSPEs[0].getSPName());
        system.assertEquals('TEST-MASP', lstSPEs[1].getSPName());
        system.assertEquals('TEST_E-0', lstSPEs[0].getEntitlement().Name);
        system.assertEquals('TEST_E-1', lstSPEs[1].getEntitlement().Name);
        
    } 
    
    
    //
    // Public methods and properties
    //
    
    public AccountEntitlementListController(ApexPages.StandardController stdController){
        this.SelectedSP = 'All';
        this.ac = [Select Id,Support_Program__c,Name from Account where Id=:stdController.getRecord().Id];
        this.loadSupportPrograms();
    }

    private final Account ac;

    private Map<Id,Support_Program__c> spSObjects = new Map<Id,Support_Program__c>();
    
    //Local variable to store all SPs with Name and Id (Name with 80 spaces+'|'+Id)
    List<String> allSPNameAndIDs = new List<String>();
    
    List<Id> allSupportProgramIds = new List<Id>();
    
    private List<SelectOption> spOptions = null;
    public List<SelectOption> getSPOptions() {
        if ( this.spOptions==null ) {
            this.spOptions = new List<SelectOption>();
            this.spOptions.add(new SelectOption('All','All'));
            //Sorting of Support program for the Entitlement List SP option.
            allSPNameAndIDs.sort();
            for(String s :allSPNameAndIDs){
                this.spOptions.add(new SelectOption(EntitlementList.GetIDFromCombineSP(s), EntitlementList.GetNameFromCombineSP(s)));
            }
            
           /* for(Id spId : this.spSObjects.keySet()) {
                this.spOptions.add(new SelectOption( spId, this.spSObjects.get(spId).Name ));
            }*/
        }
        return this.spOptions;
    }
    
    List<Id> populateAllSPList(List<String> allSPNameId) {
        List<Id> ret = new List<Id>();
        
        //Sort this list.
        allSPNameId.sort();
        for(String s : allSPNameId) {
            //Get id from this list and add into allSupportProgramIds
            ret.add( EntitlementList.GetIDFromCombineSP(s) );                
        }
        system.debug(ret);
        return ret;
    }
    
    public String SelectedSP { get; set; }
    
    public Integer getNumEntitlements(){ return this.getEntitlement().size(); }
    
    // Returns list of wrapped entitlement objs for selected SP
    public List<EntitlementList.EntitlementWrapper> getEntitlement(){
        System.assertNotEquals(null,this.SelectedSP,'Pre-condition:  SelectedSP initializes to "All", never null');

        EntitlementList el = new EntitlementList();
        List<EntitlementList.EntitlementWrapper> entData;
        List<Support_Program__c> acSpList = [select Name from Support_Program__c where (Id In :this.spSObjects.keySet()) ];
        entData = ( this.SelectedSP=='All' ) ? 
            (el.getEntitlementList( allSupportProgramIds,acSpList, false) ) : 
            (el.getEntitlementList( new List<Id>{this.SelectedSP},acSpList, false) );

        System.assertNotEquals(null,entData,'Post-condition:  no ents returns an empty list, but never a null ptr');
        return entData;
    }       
    
    //
    // Actions
    //
    
    public PageReference CreateNewCase() {
        PageReference ret = null;   
        String strFunc = System.currentPageReference().getParameters().get('strFunc');
        ID idEnt = System.currentPageReference().getParameters().get('idEnt');
        ID idSP = System.currentPageReference().getParameters().get('idSP');
        String strEntName = System.currentPageReference().getParameters().get('strEntName');
        String prmAstId ='';
        String prmAstName ='';
        EntitlementList el = new EntitlementList();
        Id contId = null;   // Account page will not have this info, pass null value. 
                            // EntitlementList class will take care of this null
        Id retUrlId = this.ac.Id;
        ret = el.CreateNewCase(retUrlId, contId, this.ac.Id, strFunc, idEnt, idSP, strEntName, prmAstId , prmAstName );
        
        return ret;
    }  

    
    //
    // Implementation methods
    //
    
    private void loadSupportPrograms() {
        this.spSObjects.clear();
        this.spSObjects.putAll( 
            [Select Id,Name,
                (Select Id,Name From Entitlements__r)
            From Support_Program__c 
            Where (Account__c=:this.ac.Id or Id=:this.ac.Support_Program__c) and (Apply_To_All_Contacts_In_Account__c=True)] );
        
        for(Id sppId : this.spSObjects.keySet()){
                allSPNameAndIDs.add(EntitlementList.CombineSPNameAndID(this.spSObjects.get(sppId).name,sppId));
                system.debug(allSPNameAndIDs);
        }   
        
        allSupportProgramIds = populateAllSPList(allSPNameAndIDs);
    }
}